-- UIScoutInfo
-- Create by cheny3
-- 斥候探索界面

require "game/ui/form/dungeon/UICommunicating"

local SCOUT_INFO           = 2;            -- 随机发言场景类型
local DISAPPEAR_DELAY_TIME = 10;           -- 发言框停留事件

-- UIScoutInfo继承自Layer
UIScoutInfo = class("UIScoutInfo", function()
    return cc.Layer:create();
end);

local resize;                     -- 适配
local slimeList = {};             -- 冈布奥动画节点
local shadowList = {};            -- 冈布奥动画阴影
local dustList = {};              -- 冈布奥动画灰尘
local nodeGroup = {};             -- 背景动画节点
local nodeGroupCopy = {};         -- 背景动画节点
local bonusList = {};             -- 奖励列表
local MAX_GRID_ROW    = 1;        -- 最大行数
local MIN_GRID_COLUMN = 3;        -- 单页显示列数
local shadowOffset = {-3, 5, 8};  -- 阴影偏移
local tiredOffset = {-10, 0, 0};  -- 疲惫动画需要移动
local shadowOffsetEx = {-5, 5, 8};
local slimeHight = {10, 8, 8};

function UIScoutInfo.create(needMask, needPlayIn)
    return UIScoutInfo.new(needMask, needPlayIn);
end

-- 构造函数
function UIScoutInfo:ctor(needMask, needPlayIn)
    self:setName("UIScoutInfo");

    -- 初始化
    local node = cc.CSLoader:createNode("layout/workshop/ScoutInfo.csb");
    self:addChild(node);
    self.node = node;

    self.isPlayingBgEffect = false;  -- 正在播放背景动画
    self.isPlayingScoutOut = false;  -- 正在播放斥候跑出动画
    self.isPlayingScoutIn  = false;  -- 正在播放斥候跑入动画
    self.needPlayInEffect  = needPlayIn;  -- 需要播放斥候跑入动画

    self.slimeStopJump = false;  -- 斥候停止跳跃
    self.bgTimeRate    = 1;      -- 背景移动速度
    self.noHideSlime = false;    -- 不要隐藏斥候
    self.slimeIsJump = false;
    self.slimeIsJumpTired = false;
    self.isTick = false;

    self.itemEffect = {};  -- 需要播放弹出效果的物件
    self.needMask = needMask; -- 需要显示蒙版

    slimeList = {};   -- 斥候节点
    shadowList = {};  -- 阴影节点
    dustList = {};    -- 灰尘节点
    bonusList = {};   -- 奖励物品

    local mask = findChildByName(self.node, "mask");
    mask:setVisible(false);

    -- 重新获取剩余时间
    local leftTime = ScoutM.getLeftTime();

    if leftTime <= 2 then
        ScoutM.refreshExploreData();
    end

    -- 滚动区域
    local scrollview = findChildByName(self.node, "CT/scroll_view");
    self.scrollView = scrollview;
    self.initHeight = scrollview:getInnerContainerSize().height;
    self.scrollView:setVisible(true);

    -- 适配
    resize(self);

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 窗口初始化
    self:initForm();

    -- 重绘
    self:redraw();

    -- 设置检查随机发言的标志
    self.checkWordsFlag = false;
end

-- 窗口初始化
function UIScoutInfo:initForm()
    local titleLabel = findChildByName(self.node, "CT/title");
    titleLabel:setString(getLocStr("slimes_in_searching"));
    TextStyleM.setTitleStyle(titleLabel);

    local timeLabel = findChildByName(self.node, "CT/subhead");
    timeLabel:setString("0:00:00");
    TextStyleM.setSubheadStyle(timeLabel);

    local note = findChildByName(self.node, "CT/note");
    local note2 = findChildByName(self.node, "CT/note2");
    local kerning = 0;
    if getLang() == "fr" then
        kerning = -2;
    end
    if #bonusList <= 0 then
        local noteStr = getLocStr("scouts_not_find_items");
        local note2Str = getLocStr("scouts_not_find_items2");
        TextStyleM.setTextStyle(note, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_DARK_BROWN);
        TextStyleM.setTextStyle(note2, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_GRAY, nil, kerning, nil, nil, nil, nil, nil, TextStyleM.getTextScale(note2Str, 30));
        note:setString(noteStr);
        note2:setString(note2Str);
        note:setVisible(true);
        note2:setVisible(true);
    end
end

-- 设置需要蒙版
function UIScoutInfo:setNeedMask(needMask)
    -- 开始探索/结束探索的通讯
    self.needMask = needMask;
end

-- 重绘
function UIScoutInfo:redraw()
    if self.needMask then
        if self.needPlayInEffect then
            -- 发起请求
            ScoutM.startExplore();
        end
        -- 需要显示蒙版
        if UIMgr:getCurrentScene():getFormByName("UICommunicating") == nil then
            local uiCommunicating = UICommunicating.create();
            uiCommunicating:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 1);
            UIMgr.getCurrentScene():addForm(uiCommunicating);
            self.needMask = false;
        end
        return;
    else
        closeCommunicatingForm();
    end

    if ScoutM.isExploring() and not self.needPlayInEffect then
        -- 正在探索中
        -- 绘制背景动画
        if ScoutM.getLeftTime() <= 0 then
            self.bgTimeRate = 2;
            self:backgroundShow();
            self:removeScout();
            self:redrawSlimeTired(ScoutM.getScoutCount());
        else
            self:backgroundShow();
            self:removeScout();
            self:redrawSlime(ScoutM.getScoutCount());
        end

        -- 倒计时
        self:redrawLeftTime();

        -- 奖励列表
        self:redrawItems();
    elseif ScoutM.isExploring() then
        -- 刚刚开始探索
        self.needMask = false;
        -- 跑进来动画
        self:playScoutInEffect(ScoutM.getScoutCount());

        local function playNormalEffect()
            -- 绘制背景动画
            self:backgroundShow();

            -- 清除斥候
            self:removeScout();

            -- 斥候跳跃
            self:redrawSlime(ScoutM.getScoutCount());

            -- 倒计时
            self:redrawLeftTime();

            -- 奖励列表
            self:redrawItems();

            self.isPlayingScoutIn = false;

            -- 去掉蒙版，不让点击
            local mask = findChildByName(self.node, "mask");
            mask:setVisible(false);

            -- 按钮恢复
            local btnCallBack = findChildByName(self.node, "CT/call_back");
            btnCallBack:setTouchEnabled(true);
            btnCallBack:setBright(true);
        end

        performWithDelay(self.node, playNormalEffect, 2);
    else
        local function closeWindow()
            -- 播放炼金界面斥候进来的动画
            local uiNewWorkshop = UIMgr.getCurrentScene():getFormByName("UINewWorkshop");
            if uiNewWorkshop ~= nil then
                uiNewWorkshop:playScoutInEffect(ScoutM.getScoutCount());
                if self.bonusEffectList and #self.bonusEffectList > 0 then
                    uiNewWorkshop:setNeedPlayBagOpen(true);
                else
                    uiNewWorkshop:setNeedPlayBagOpen(false);
                end
                uiNewWorkshop:playItemsFlyIn(self.bonusEffectList);
            end

            -- 结束探索,关闭界面
            UIMgr.getCurrentScene():removeFormByName("UIScoutInfo");
        end

        -- 播放探索界面斥候出去动画
        self:playScoutOutEffect(ScoutM.getScoutCount());
        performWithDelay(self.node, closeWindow, 2);
    end
end

-- 停止所有背景动画
function UIScoutInfo:stopBgAction()
    self.isPlayingBgEffect = false;
    for i = 1, 4 do
        if nodeGroup[i] ~= nil and nodeGroupCopy[i] ~= nil then
            nodeGroup[i]:stopAllActions();
            nodeGroupCopy[i]:stopAllActions();
        end
    end
end

-- 背景的动画显示
function UIScoutInfo:backgroundShow()
    -- 主节点
    local panel = findChildByName(self.node, "CT/panel");
    local bgNode = findChildByName(panel, "bg");

    -- panel的宽度
    local panelWidth = panel:getContentSize().width;

    -- 设置表明正在播放动画
    if self.isPlayingBgEffect then
        -- 直接返回
        return;
    end

    self.isPlayingBgEffect = true;

    -- 移动时间
    local factors = {50, 35, 28, 12};

    -- 背景节点名字
    local nodeName = {"cloud", "far", "middle", "near"};
    local nodePositionX = {};

    for i = 1, 4 do
        -- 获取节点
        nodeGroup[i] = findChildByName(bgNode, nodeName[i]);
        nodeGroupCopy[i] = findChildByName(bgNode, nodeName[i] .."_copy");
        nodeGroup[i]:stopAllActions();
        nodeGroupCopy[i]:stopAllActions();
        nodePositionX[i] = nodeGroupCopy[i]:getPositionX() * panelWidth / 500;
        nodeGroup[i]:setPosition(-nodePositionX[i], nodeGroup[i]:getPositionY());
        nodeGroupCopy[i]:setPosition(0, nodeGroup[i]:getPositionY());
    end

    -- 移动动画
    local countList = {1, 1, 1, 1};

    local function move(nodeFlag)
        --创建动作
        local moveAction1 = cc.MoveTo:create(factors[nodeFlag] * self.bgTimeRate, cc.p(0, nodeGroup[nodeFlag]:getPositionY()));
        local moveAction2 = cc.MoveTo:create(factors[nodeFlag] * self.bgTimeRate, cc.p(nodePositionX[nodeFlag], nodeGroup[nodeFlag]:getPositionY()));
        if countList[nodeFlag] == 1 then
            nodeGroup[nodeFlag]:setPosition(cc.p(-nodePositionX[nodeFlag], nodeGroup[nodeFlag]:getPositionY()));
            nodeGroupCopy[nodeFlag]:setPosition(cc.p(0, nodeGroup[nodeFlag]:getPositionY()));
            nodeGroup[nodeFlag]:stopAllActions();
            nodeGroupCopy[nodeFlag]:stopAllActions();
            nodeGroup[nodeFlag]:runAction(moveAction1);
            nodeGroupCopy[nodeFlag]:runAction(moveAction2);
            countList[nodeFlag] = 2;
        else
            nodeGroup[nodeFlag]:setPosition(cc.p(0, nodeGroup[nodeFlag]:getPositionY()));
            nodeGroupCopy[nodeFlag]:setPosition(cc.p(-nodePositionX[nodeFlag], nodeGroup[nodeFlag]:getPositionY()));
            nodeGroup[nodeFlag]:runAction(moveAction2);
            nodeGroupCopy[nodeFlag]:runAction(moveAction1);
            countList[nodeFlag] = 1;
        end
    end

    for i = 1, 4 do
        local function show()
            if self.slimeStopJump then
                return;
            end
            move(i);
            performWithDelay(self.node, show, factors[i] * self.bgTimeRate);
        end
        show();
    end
end

-- 清除斥候冈布奥
function UIScoutInfo:removeScout()
    local posParent = findChildByName(self.node, "CT/panel/pos_parent");
    posParent:stopAllActions();
    -- 清空
    for i = 1, #shadowList do
        posParent:removeChild(shadowList[i]);
        posParent:removeChild(slimeList[i]);
    end
    shadowList = {};
    slimeList = {};
    self.slimeIsJump = false;
    self.slimeIsJumpTired = false;
end

-- 绘制斥候冈布奥普通跳跃
function UIScoutInfo:redrawSlime(showNum)
    local posParent = findChildByName(self.node, "CT/panel/pos_parent");
    posParent:stopAllActions();

    if showNum > 3 then
        showNum = 3;
    end

    if self.slimeIsJump then
        return;
    end

    self.slimeIsJump = true;

    -- 先清空
    for i = 1, #shadowList do
        posParent:removeChild(shadowList[i]);
        posParent:removeChild(slimeList[i]);
    end
    shadowList = {};
    slimeList = {};

    -- 先创建阴影,保证所有阴影在冈布奥后面
    for i = 1, showNum do
        local pos = posParent:getChildByName("pos" .. tostring(i));
        local shadow = ccui.ImageView:create();
        shadowList[i] = shadow;
        shadow:setScale(0.8);
        posParent:addChild(shadow);
        shadow:setPosition(cc.p(pos:getPositionX() + shadowOffsetEx[i], pos:getPositionY() - 25));
        shadow:loadTexture("images/ui/workshop/shadow2.png", 1);
        shadow:setVisible(true);
    end

    -- 创建冈布奥
    for i = 1, showNum do
        local pos = posParent:getChildByName("pos" .. tostring(showNum - i + 1));
        local slime = ccui.ImageView:create();
        slimeList[i] = slime;
        posParent:addChild(slime);
        slime:setPosition(pos:getPosition());
        --slime:loadTexture("images/ui/workshop/scout"..tostring(showNum - i + 1)..".png");
        slime:loadTexture(getScoutIconPath(showNum - i + 1));
        local posX = slime:getPositionX();
        local posY = slime:getPositionY();

        local function jump()
            if self.slimeStopJump then
                return;
            end

            local jumps = math.ceil(1);
            local height = math.ceil(slimeHight[showNum - i + 1]);
            local jumpBy = cc.JumpTo:create(0.4 * jumps, cc.p(posX, posY), height, jumps);
            slimeList[i]:runAction(jumpBy);

            local r = math.random(300, 800);
            if self.slimeIsJump then
                performWithDelay(slimeList[i], jump, 0.4 * jumps + 0.1 + i/50);
            end
        end

        -- jump();
        -- 冈布奥跳跃初始时间不同
        performWithDelay(posParent, jump, (i - 1) * 0.2 + 0.01);
    end

    -- 检查随机发言
    local function callback()
        self:checkRandomWords();
    end
    performWithDelay(self,callback,0.5)
end

-- 绘制冈布奥疲惫跳跃
function UIScoutInfo:redrawSlimeTired(showNum)
    local posParent = findChildByName(self.node, "CT/panel/pos_parent");
    posParent:stopAllActions();

    if showNum > 3 then
        showNum = 3;
    end

    if self.slimeIsJumpTired then
        return;
    end

    self.slimeIsJumpTired = true;

    -- 先清空
    for i = 1, #shadowList do
        posParent:removeChild(shadowList[i]);
        posParent:removeChild(slimeList[i]);
    end
    shadowList = {};
    slimeList = {};

    -- 先创建阴影,保证所有阴影在冈布奥后面
    for i = 1, showNum do
        local pos = posParent:getChildByName("pos" .. tostring(i));
        local shadow = ccui.ImageView:create();
        shadowList[i] = shadow;
        shadow:setScale(0.8);
        posParent:addChild(shadow);
        shadow:setPosition(cc.p(pos:getPositionX() + shadowOffset[i], pos:getPositionY() - 25));
        shadow:loadTexture("images/ui/workshop/shadow2.png", 1);
        shadow:setVisible(true);
    end

    -- 创建冈布奥动画节点
    for i = 1, showNum do
        local pos = posParent:getChildByName("pos" .. tostring(showNum - i + 1));
        local slime = cc.Node:create();
        slimeList[i] = slime;
        posParent:addChild(slime);
        slime:setPosition(pos:getPosition());

        -- 由于动画偏移
        slime:setPositionX(slime:getPositionX() + tiredOffset[showNum - i + 1]);

        local function playAction()
            if self.slimeStopJump then
                return;
            end
            if slime == nil then
                return;
            end

            slimeList[i]:removeAllChildren();
            -- 播放叹气特效
            self:playScoutEffect(slimeList[i], 1500 + showNum - i);
            performWithDelay(pos, playAction, 2);
        end

        performWithDelay(slime, playAction, (i - 1) * 0.2 + 0.01);
    end

    -- 检查随机发言
    local function callback()
        self:checkRandomWords();
    end
    performWithDelay(self,callback,0.5)
end

-- 播放特效
function UIScoutInfo:playScoutEffect(parentNode, effectId)
    local effectAniam = createEffectAnim(effectId);
    effectAniam:setPositionY(effectAniam:getPositionY() - 25);
    parentNode:addChild(effectAniam);
    -- 23祯开始/69祯结束
    effectAniam:play(23, 68);
end

-- 重绘奖励
function UIScoutInfo:redrawItems()
    local scrollView = findChildByName(self.node, "CT/scroll_view");
    local note = findChildByName(self.node, "CT/note");
    local note2 = findChildByName(self.node, "CT/note2");
    local kerning = 0;
    if getLang() == "fr" then
        kerning = -2;
    end

    -- 重新获取奖励列表
    bonusList = ScoutM.queryBonus();
    note:setVisible(false);
    note2:setVisible(false);

    if #bonusList <= 0 then
        -- 没有奖励
        local noteStr = getLocStr("scouts_not_find_items");
        local note2Str = getLocStr("scouts_not_find_items2");
        TextStyleM.setTextStyle(note, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_DARK_BROWN);
        TextStyleM.setTextStyle(note2, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_GRAY, nil, kerning, nil, nil, nil, nil, nil, TextStyleM.getTextScale(note2Str, 30));
        note:setString(noteStr);
        note2:setString(note2Str);
        note:setVisible(true);
        note2:setVisible(true);
        return;
    end

    scrollView:setAnchorPoint(cc.p(0.5, 0.5));

    -- 图标间距(横向)
    local wGap = 10;

    -- 图标间距(纵向)
    local hGap = 0;

    -- 图标宽度
    local iconWidth = 126;

    -- 图片高度
    local iconHeight = 126;

    local topHGap  = 0;
    local leftWGap = 10;

    -- 总数
    local totalCount = #bonusList;

    self.scrollView.rows = {};
    self.scrollView:removeAllChildren();

    local itemNode = cc.CSLoader:createNode("layout/combat_stat/CombatStatItem.csb");
    -- 缩放90%
    itemNode:setScale(0.9);

    -- @param windowNode    界面节点
    -- @param scrollNode    容器节点
    -- @param itemNode      单元格的节点
    -- @param totalNum      单元格总数
    -- @param maxRowNum     最大行数
    -- @param pageColNum    单页可以显示下的列数
    -- @param wGap          单元格间距(横向) 这里作为最小值使用
    -- @param hGap          单元格间距(纵向)
    -- @param iconWidth     单元格宽度
    -- @param iconHeight    单元格高度
    -- @param topHGap       上方留白
    -- @param leftWGap      左右留白  这里作为最小值使用
    initScrollGridsHorizontal(self, self.scrollView, itemNode, totalCount, MAX_GRID_ROW, MIN_GRID_COLUMN, wGap, hGap, iconWidth, iconHeight, topHGap, leftWGap);
    -- 绘制物品信息
    self:drawItemInfo();
end

-- 绘制物品详细信息
function UIScoutInfo:drawItemInfo()
    for i = 1, #bonusList do
        local grid = self.scrollView:getChildByName("item" .. i);
        if grid then
            self:initItem(grid, bonusList[i]);
        end
    end
end

-- 初始化单个格子
function UIScoutInfo:initItem(node, info)
    local classId = info["class_id"];
    local num = info["count"] * info["times"];
    local iconPath;

    node:setPositionY(node:getPositionY() + 30);
    node:setVisible(false);

    -- 图标
    local icon = findChildByName(node, "icon");
    if classId == "money" then
        -- TODO: 本来应该做成道具的
        local unit = info["count"] / ScoutM.queryExplore("scout_count");
        if unit == 1000 then
            classId = 1509;
        elseif unit == 200 then
            classId = 1508;
        else
            classId = 1507;
        end
        iconPath = getItemIconPath(ItemM.query(classId, "icon"));
        -- 由于道具描述为固定，这里改变一下数量
        num = info["times"] * ScoutM.queryExplore("scout_count");
    elseif classId == "gem" then
        classId = 1510;
        iconPath = getItemIconPath(ItemM.query(classId, "icon"));
    else
        iconPath = getItemIconPath(ItemM.query(classId, "icon"));
    end
    icon:loadTexture(iconPath);

    -- 数量
    local numLabel = findChildByName(node, "num");
    TextStyleM.setTextStyle(numLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    numLabel:setString(tostring(num));
    numLabel:setFontSize(TextStyleM.TEXT_SIZE_SMALL);

    -- 星星
    local starNode = findChildByName(node, "star");
    starNode:setVisible(false);

    -- 点击处理
    local bg = findChildByName(node, "bg");
    bg:addTouchEventListener(function(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("workshop_material");
            if classId == "money" then
                alert(getLocStr("money"))
            elseif classId == "gem" then
                alert(string.format(getLocStr("gain_scout_items"), FieldsM.getFieldName("gem"), num));
            else
                -- 显示道具详细信息
                local uiItemDesc = UIItemDesc.create(classId);
                UIMgr:getCurrentScene():addForm(uiItemDesc);
            end
        end
    end);

    -- 刚出来的物品需要播放动画
    if table.indexOf(self.itemEffect, classId) ~= -1 then
        local function callBack()
            if #self.itemEffect == 0 then
                return;
            end
            node:setScale(0.1);
            self:playItemOutEffect(node);
            -- 播完就清除
            self.itemEffect = {};
        end
        performWithDelay(node, callBack, 0.2);
    else
        node:setVisible(true);
    end
end

-- 物品跳出来动画
function UIScoutInfo:playItemOutEffect(itemNode)
    itemNode:setVisible(true);
    local scaleReady = cc.ScaleTo:create(0.01, 0.1);
    local scaleUp = cc.ScaleTo:create(0.3, 1.0);
    local scaleDown = cc.ScaleTo:create(0.15, 0.7);
    local scaleNormal = cc.ScaleTo:create(0.15, 0.9);
    itemNode:runAction(cc.Sequence:create(scaleReady, scaleUp, scaleDown, scaleNormal));
end

-- 需要播放动画的物品
function UIScoutInfo:setItemOutClassId(classId)
    -- 一次只播放一个
    self.itemEffect = { classId };
end

-- 注册事件处理回调函数
function UIScoutInfo:registerEventCallback()
    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            cclog("UIScoutInfo 界面析构清理");
            -- 清除冈布奥
            -- self:removeScout();
            -- 停止背景动画
            -- self:stopBgAction();
            -- 移除监听事件
            EventMgr.removeAll("UIScoutInfo");
            local uiForm = UIMgr.getCurrentScene():getFormByName("UINewWorkshop");
            if uiForm then
                -- 显示底部信息
                uiForm:showBottomMenu();
            end

            -- 关闭正在通信界面
            closeCommunicatingForm();
        elseif ev == "enter" then
            -- 更新斥候信息监听
            EventMgr.register("UIScoutInfo", event.SCOUT_INFO_UPDATE, function()
                self:updateScoutInfo();
            end);
            local uiForm = UIMgr.getCurrentScene():getFormByName("UINewWorkshop");
            if uiForm then
                -- 隐藏底部信息
                uiForm:hideBottomMenu();
            end
        end
    end);
end

-- 斥候信息更新的时候
function UIScoutInfo:updateScoutInfo()
    -- 重绘
    self:redraw();
end

-- 设置需要播放跑进来动画
function UIScoutInfo:setNeedPlayInEffect(need)
    self.needPlayInEffect = need;
end

-- 斥候跑进来动画
function UIScoutInfo:playScoutInEffect(showNum)
    local posParent = findChildByName(self.node, "CT/panel/pos_parent");

    -- 斥候动画停止
    self.slimeStopJump = true;

    -- 不要隐藏节点
    self.noHideSlime = true;

    if showNum > 3 then
        showNum = 3;
    end

    self.needPlayInEffect = false;

    if self.isPlayingScoutOut or self.isPlayingScoutIn then
        return;
    end

    -- 正在播放斥候跑出去动画
    self.isPlayingScoutIn = true;
    AudioM.playFx("explore");

    -- 加蒙版，不让点击
    local mask = findChildByName(self.node, "mask");
    mask:setVisible(true);
    mask:setOpacity(0);

    -- 按钮置灰
    local btnCallBack = findChildByName(self.node, "CT/call_back");
    btnCallBack:setTouchEnabled(false);
    btnCallBack:setBright(false);

    -- 跑动距离
    local panel = findChildByName(self.node, "CT/panel");
    local panelWidth = panel:getContentSize().width;
    local slimeRunDistance = panelWidth / 2 + 50;

    -- 先清空
    for i = 1, #shadowList do
        posParent:removeChild(shadowList[i]);
        posParent:removeChild(slimeList[i]);
    end
    shadowList = {};
    slimeList = {};

    -- 先创建阴影,保证所有阴影在冈布奥后面
    for i = 1, showNum do
        local pos = posParent:getChildByName("pos" .. tostring(i));
        local shadow = ccui.ImageView:create();
        shadowList[i] = shadow;
        shadow:setScale(0.8);
        posParent:addChild(shadow);
        shadow:setPosition(cc.p(pos:getPositionX() + slimeRunDistance + shadowOffset[i], pos:getPositionY() - 25));
        shadow:loadTexture("images/ui/workshop/shadow2.png", 1);
        shadow:setVisible(true);
    end

    -- 创建灰尘节点
    for i = 1, showNum do
        local pos = posParent:getChildByName("pos" .. tostring(showNum - i + 1));
        local dustNode = cc.Node:create();
        dustList[i] = dustNode;
        dustNode:setScaleX(-1);
        posParent:addChild(dustNode);
        dustNode:setPosition(cc.p(pos:getPositionX() + slimeRunDistance + 35, pos:getPositionY() - 10));
    end

    -- 创建节点
    for i = 1, showNum do
        local pos = posParent:getChildByName("pos" .. tostring(showNum - i + 1));
        local slime = cc.Node:create();
        local slimeIcon = ccui.ImageView:create();
        --slimeIcon:loadTexture("images/ui/workshop/scout"..tostring(showNum - i + 1)..".png");
        slimeIcon:loadTexture(getScoutIconPath(showNum - i + 1));
        posParent:addChild(slime);
        slime:addChild(slimeIcon);
        slime:setPosition(cc.p(pos:getPositionX() + slimeRunDistance, pos:getPositionY()));
        slimeList[showNum - i + 1] = slime;
    end

    -- 跑出屏幕动画
    local function moveIn()
        -- 灰尘节点
        local countList = {0, 0, 0};

        local function showDust(dustFlag)
            local dustNode = dustList[dustFlag];
            dustNode:removeAllChildren();
            playEffect(dustNode, 1503, slimeRunDistance * (countList[dustFlag]) / 10 + 5, -15, nil);
        end

        for i = 1, showNum do
            local function showDustPlay()
                showDust(i);
                if countList[i] <= 10 then
                    performWithDelay(self.node, showDustPlay, 0.1);
                else
                    dustList[i]:removeAllChildren();
                end
                countList[i] = countList[i] + 1;
            end
            showDustPlay();
        end

        for i = 1, showNum do
            local slimeNode = slimeList[i];
            local shadowNode = shadowList[i];
            local jumps = math.ceil(10);
            --local height = math.random(3, 5);
            local height = 0;
            local jumpBy = cc.JumpTo:create(0.1 * jumps, cc.p(slimeNode:getPositionX() - slimeRunDistance,
                slimeNode:getPositionY()), height, jumps);
            local jumpBy2 = cc.JumpTo:create(0.1 * jumps, cc.p(shadowNode:getPositionX() - slimeRunDistance,
                shadowNode:getPositionY()), 0, jumps)
            slimeNode:runAction(jumpBy);
            shadowNode:runAction(jumpBy2);
        end

        -- 移除所有节点
        local function removeNode()
            --self:removeScout();
            self.noHideSlime = false;
            self.slimeStopJump = false;
        end
        performWithDelay(posParent, removeNode, 1);
    end

    -- 跑进来动画
    moveIn();
end

-- 斥候跑出动画
function UIScoutInfo:playScoutOutEffect(showNum)
    local posParent = findChildByName(self.node, "CT/panel/pos_parent");

    -- 斥候动画停止
    self.slimeStopJump = true;

    -- 不要隐藏节点
    self.noHideSlime = true;

    -- 背景动画停止
    self:stopBgAction();

    if showNum > 3 then
        showNum = 3;
    end

    if self.isPlayingScoutOut or self.isPlayingScoutIn then
        return;
    end

    -- 正在播放斥候跑出去动画
    self.isPlayingScoutOut = true;

    -- 加蒙版，不让点击
    local mask = findChildByName(self.node, "mask");
    mask:setVisible(true);
    mask:setOpacity(0);

    AudioM.playFx("explore");
    -- 按钮置灰
    local btnCallBack = findChildByName(self.node, "CT/call_back");
    btnCallBack:setTouchEnabled(false);
    btnCallBack:setBright(false);

    -- 先清空
    for i = 1, #shadowList do
        posParent:removeChild(shadowList[i]);
        posParent:removeChild(slimeList[i]);
    end
    shadowList = {};
    slimeList = {};

    -- 先创建阴影,保证所有阴影在冈布奥后面
    for i = 1, showNum do
        local pos = posParent:getChildByName("pos" .. tostring(i));
        local shadow = ccui.ImageView:create();
        shadowList[i] = shadow;
        shadow:setScale(0.8);
        posParent:addChild(shadow);
        shadow:setPosition(cc.p(pos:getPositionX(), pos:getPositionY() - 25));
        shadow:loadTexture("images/ui/workshop/shadow2.png", 1);
        shadow:setVisible(true);
    end

    -- 创建灰尘节点
    for i = 1, showNum do
        local pos = posParent:getChildByName("pos" .. tostring(showNum - i + 1));
        local dustNode = cc.Node:create();
        dustList[i] = dustNode;
        posParent:addChild(dustNode);
        dustNode:setPosition(cc.p(pos:getPositionX() - 15, pos:getPositionY() - 10));
    end

    -- 创建节点
    for i = 1, showNum do
        local pos = posParent:getChildByName("pos" .. tostring(showNum - i + 1));
        local slime = cc.Node:create();
        local slimeIcon = ccui.ImageView:create();
        --slimeIcon:loadTexture("images/ui/workshop/scout"..tostring(showNum - i + 1)..".png");
        slimeIcon:loadTexture(getScoutIconPath(showNum - i + 1));
        posParent:addChild(slime);
        slimeIcon:setFlippedX(true);
        slime:addChild(slimeIcon);
        slime:setPosition(cc.p(pos:getPositionX(), pos:getPositionY()));
        slimeList[showNum - i + 1] = slime;
    end

    -- 跑出屏幕动画
    local function moveOut()
        -- 灰尘节点
        local countList = {0, 0, 0};

        local panel = findChildByName(self.node, "CT/panel");

        -- panel的宽度
        local panelWidth = panel:getContentSize().width;
        local slimeRunDistance = panelWidth / 2 + 50;

        local function showDust(dustFlag)
            local dustNode = dustList[dustFlag];
            dustNode:removeAllChildren();
            playEffect(dustNode, 1503, slimeRunDistance / 10 * countList[dustFlag] - 5, -15, nil);
        end

        for i = 1, showNum do
            local function showDustPlay()
                showDust(i);
                if countList[i] <= 10 then
                    performWithDelay(self.node, showDustPlay, 0.1);
                else
                    dustList[i]:removeAllChildren();
                end
                countList[i] = countList[i] + 1;
            end
            showDustPlay();
        end

        for i = 1, showNum do
            local slimeNode = slimeList[i];
            local shadowNode = shadowList[i];
            local jumps = math.ceil(10);
            --local height = math.random(3, 5);
            local height = 0;
            local jumpBy = cc.JumpTo:create(0.1 * jumps, cc.p(slimeNode:getPositionX() + slimeRunDistance,
                slimeNode:getPositionY()), height, jumps);
            local jumpBy2 = cc.JumpTo:create(0.1 * jumps, cc.p(shadowNode:getPositionX() + slimeRunDistance,
                shadowNode:getPositionY()), 0, jumps)
            slimeNode:runAction(jumpBy);
            shadowNode:runAction(jumpBy2);
        end

        -- 移除所有节点
        local function removeNode()
            self:removeScout();
            self.noHideSlime = false;
        end
        performWithDelay(posParent, removeNode, 1);
    end

    -- 跑出去动画
    moveOut();
end

-- 定时回调绘制倒计时
function UIScoutInfo:redrawLeftTime()
    local timeLabel = findChildByName(self.node, "CT/subhead");
    local title = findChildByName(self.node, "CT/title");
    local pos_parent = findChildByName(self.node, "CT/panel/pos_parent");

    -- 重新获取剩余时间
    local leftTime = ScoutM.getLeftTime();

    if self.isTick then
        if leftTime < 0 then
            local function callback()
                -- 重新获取奖励列表
                bonusList = ScoutM.queryBonus();
                timeLabel:setString(string.format(getLocStr("scout_find_items_number"), #bonusList));
                title:setString(getLocStr("finish_seaching"));
            end
            performWithDelay(self, callback, 1);
        end
        return;
    end

    self.isTick = true;

    local function tick()
        if not ScoutM.isExploring() then
            return;
        end

        if leftTime == nil then
            timeLabel:setString("0:00:00");
            return;
        elseif leftTime <= 8 and leftTime > 0 then
            -- 即将探索结束
            -- 背景速度变化
            self.bgTimeRate = 2;
        elseif leftTime < 0 then
            -- 重新获取奖励列表
            bonusList = ScoutM.queryBonus();
            timeLabel:setString(string.format(getLocStr("scout_find_items_number"), #bonusList));
            title:setString(getLocStr("finish_seaching"));
            -- 探索完成
            -- 绘制冈布奥疲惫动画
            self:removeScout();
            self:redrawSlimeTired(ScoutM.getScoutCount());
            return;
        end

        if leftTime <= 2 then
            -- 主动去请求数据
            ScoutM.refreshExploreData();
        end

        local timeText;
        local hour, min, second;
        local minText, secondText;
        hour = math.floor(leftTime / 3600);
        min = math.floor((leftTime - hour * 3600) / 60);
        second = math.floor(leftTime % 60);

        if min < 10  then
            minText = "0" .. tostring(min);
        else
            minText = tostring(min);
        end

        if second < 10 then
            secondText = "0" .. tostring(second);
        else
            secondText = tostring(second);
        end

        if hour <= 0 then
            -- 小时位不显示
            timeText = minText .. ":" .. secondText;
        else
            timeText = tostring(hour) .. ":" .. minText .. ":" .. secondText;
        end

        timeLabel:setString(timeText);
        leftTime = leftTime - 1;

        performWithDelay(self, tick, 1);
    end
    tick();
end

-- 注册点击事件
function UIScoutInfo:registerTouchEvent()
    -- 注册召唤斥候按钮事件
    local btnCallBack = findChildByName(self.node, "CT/call_back");
    local function onCallBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            local wordsNode = findChildByName(self.node, "CT/words_node");
            wordsNode:removeAllChildren();
            if self.isPlayingScoutOut or self.isPlayingScoutIn then
                -- 正在播放跑出去/进来动作
                return;
            end

            -- 可能被刷掉了bonusList/召回前把东西记录下来
            self.bonusEffectList = table.deepcopy(bonusList);

            -- 需要蒙版
            self:setNeedMask(true);
            -- 重绘
            self:redraw();

            -- 按钮音效
            AudioM.playFx("button_click");

            -- 召回斥候
            ScoutM.stopExplore();
        end
    end
    AddTouchEventListener(btnCallBack, onCallBackClick);
    TextStyleM.setTextStyle(btnCallBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnCallBack:setTitleText(getLocStr("scout_call_back"));

    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            if self.isPlayingScoutOut then
                return;
            end
            -- 关闭界面
            AudioM.playFx("button_return");
            UIMgr.getCurrentScene():removeFormByName("UIScoutInfo");
        end
    end
    AddTouchEventListener(btnBack, onBackClick);
    AddBackEventHandler(self, btnBack, btnBack.touchEventListener);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));
end

-- 检查随机发言的状态
function UIScoutInfo:checkRandomWords()
    -- 斥候ID为17
    local level = AlchemyWorkshopM.getStrengthenLevel(17);
    if level < 2 then
        return;
    end

    if self.checkWordsFlag then
         return;
    end

    self.checkWordsFlag = true;
    local sceneType = SCOUT_INFO;
    local wordsId = FormulaM.invoke("CALC_RANDOM_WORDS", sceneType);
    if not wordsId then
        return;
    end

    -- 查询随机发言的内容
    local content = RandomWordsM.query(sceneType, wordsId, "content");

    local wordsNode = findChildByName(self.node, "CT/words_node");
    wordsNode:removeAllChildren();
    createWordsFrame(wordsNode, content, WORDS_FRAME_ARROW_TOP_RIGHT);
end

-- 适配
resize = function(self)
    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT置于正中间并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");

    -- mask置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "mask");
end

